#!/usr/bin/env ruby

require "yaml"

if ARGV.length != 1
  puts "path to stainless configuration must be provided as the only argument"
  exit 1
end

config = YAML.load_file(ARGV[0])
mappingPath = "internal/app/cf-terraforming/cmd/resource_to_endpoint_mapping.go"
output = ""

def skipped_resource?(terraform_name)
  [
    # deprecated and backend service support automatic migrations
    "firewall_rule",
    "firewall_filter",

    # doesn't work with outer wrap parameters
    "cloud_connector_rules",

    # terraform can't get the content (may be bundled, etc)
    "workers_script"
  ].include?(terraform_name)
end

def terraform_name(v)
  if v.is_a?(Hash)
    # don't generate if we've explicitly disabled the resource
    return nil if v.dig("terraform") == false
    return nil if v.dig("terraform", "resource") == false

    return v.dig("terraform", "name")
  elsif v.is_a?(String)
    return v
  end

  return nil
end

def has_subresources(v)
  return false unless v.is_a?(Hash)
  return v.has_key?("subresources")
end

def list_endpoint(v)
  return { list: nil, get: nil } unless v.is_a?(Hash)

  output = {list: nil, get: nil}
  list_operation = v.dig("methods", "list")
  get_operation = v.dig("methods", "get")

  return { list: nil, get: nil } if list_operation.nil? && get_operation.nil?

  if list_operation.is_a?(String)
    return { list: nil, get: nil } if !list_operation.start_with?("get")
    output[:list] = list_operation.delete_prefix("get ")
  end

  if get_operation.is_a?(String)
    return { list: nil, get: nil } if !get_operation.start_with?("get")
    output[:get] = get_operation.delete_prefix("get ")
  end

  # if we have a hash it means the endpoint has a
  # nested structure and we need the `endpoint` value
  # instead of just the `list` operation value.
  if list_operation.is_a?(Hash) && !list_operation.nil?
    return { list: nil, get: nil } if !list_operation.dig("endpoint").start_with?("get")
    output[:list] = list_operation.dig("endpoint").delete_prefix("get ")
  end

  # if we have a hash it means the endpoint has a
  # nested structure and we need the `endpoint` value
  # instead of just the `list` operation value.
  if get_operation.is_a?(Hash) && !get_operation.nil?
    return nil if !get_operation.dig("endpoint").start_with?("get")
    output[:get] = get_operation.dig("endpoint").delete_prefix("get ")
  end

  return output
end

def build_output(output, config)
  terraform_name = terraform_name(config)
  endpoint = list_endpoint(config)

  if !terraform_name.nil? && !endpoint.nil? && !skipped_resource?(terraform_name)
    output << "
    \"cloudflare_#{terraform_name}\": map[string]string{
      \"list\":\"#{endpoint[:list]}\",
      \"get\":\"#{!endpoint[:get].nil? ? endpoint[:get] : endpoint[:list]}\",
    },"
  end

  return if config["subresources"].nil?
  config["subresources"].each do |k, v|
    build_output(output, v)
  end
end

config["resources"].keys.each do |k, v|
  c = config["resources"][k]
  build_output(output, c)
end


File.write(mappingPath, %Q(
// This file is automatically generated. Any manual edits here will be overwritten on the next update.
package cmd

var resourceToEndpoint = map[string]map[string]string{
  #{output}
}
))

Kernel.system("gofmt -s -w #{mappingPath}")
